<?php
/**
 * @package   auto_occasion
 * @subpackage 
 * @author    CMS
 * @copyright 2011
 * @license    All rights reserved
 */
require_once(LIB_PATH.'phpMailer/class.phpmailer.php');


/**
 * Classe permettant de gérer les injection faites au site (sql)
 *
 */
class injectionSrv {

    /**
     * Récupère l'ip de l'internaute
     * @return string 
     */
    public static function getIp () {

        if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
		    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif(isset($_SERVER['HTTP_CLIENT_IP'])) { 
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } else { 
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        //$ip = '58.177.255.255';
        return $ip;
    }


    /**
     * Vérifie si l'internaute vient ou non d'un pays interdit
     * 
     * @return boolean true if allwed false if not
     */
    public static function isAllowed () {
        $ret = false;
        $ip  = self::getIp();
        // ip sans .
        if ($ip) {
            $ip          = self::IPAddress2IPNumber($ip);
            $countryCode = self::getCountryIdFromIp($ip); // ex CH ...
            // vérifie si le pays est dans le liste des pays interdit
            return self::isThisCountryAllowed($countryCode);
        }

        return $ret;
    }

    /**
     * Retourne l'adresse ip sans les .
     * 
     * @return double
     */
    public static function IPAddress2IPNumber($dotted) {
        $dotted = preg_split( "/[.]+/", $dotted);
        $ip = (double) ($dotted[0]*16777216)+($dotted[1]*65536)+($dotted[2]*256)+($dotted[3]);

        return $ip;
    }

    /**
     * Vérifie si l'ip codé numériquement est dans la table ao_ip_to_country
     * 
     * @return char code du pays ex CH etc ...
     */
    public static function getCountryIdFromIp($ip) {
        $cnx = jDb::getConnection();
        $sql = " SELECT COUNTRY_CODE FROM ao_ip_to_country WHERE $ip BETWEEN IP_FROM AND IP_TO";

        $res     = $cnx->query($sql)->fetch();

        return (isset($res->COUNTRY_CODE)) ? $res->COUNTRY_CODE : "";
    }

    /**
     * get country name
     * 
     * @return char code du pays ex CH etc ...
     */
    public static function getCountry($ip) {
        $cnx = jDb::getConnection();
        $sql = " SELECT COUNTRY_NAME FROM ao_ip_to_country WHERE $ip BETWEEN IP_FROM AND IP_TO";

        $res     = $cnx->query($sql)->fetch();

        return $res->COUNTRY_NAME;
    }

    /**
     * Vérifie si le pays fait parti des pays interdits
     * 
     * @return boolean true if allowed false if not
     */
    public static function isThisCountryAllowed($countryCode) {
        $ret = true;
        jClasses::inc('commun~paysSrv');

        $interdit = paysSrv::interdit();
        if (in_array($countryCode, $interdit)) {
            $ret = false;
        }

        return $ret;
    }


    /**
     * Récupère la localisation de l'internaute
     * 
     * @return string
     */
    public static function getLocalisation() {
        $ip = self::getIp() ;
        if (@file_get_contents("http://www.ipcheck.fr/api.php")) {
            $localisation = file_get_contents("http://www.ipcheck.fr/api.php?objet=pays&ip=".$ip."&choix=0").'|'.file_get_contents("http://www.ipcheck.fr/api.php?objet=region&ip=".$ip).'|'.file_get_contents("http://www.ipcheck.fr/api.php?objet=ville&ip=".$ip);
        } else {
            $hostip       = "http://api.hostip.info/get_html.php?ip=$ip"."&position=true";
            $localisation = (@file_get_contents($hostip)) ? @file_get_contents($hostip) : "||";
        }

        if($localisation == "||"){
            $ip2          = self::IPAddress2IPNumber($ip);
            $localisation = self::getCountry($ip2);
        }	

        return $localisation ;
    }


        /**
     * Liste des valeurs à contrôler dans l'url
     * 
     * @return array
     */
    public static function liste () {

        $sql = " SELECT * FROM ao_injection_names ORDER BY libelle_injection";
        $jdb = jDb::getDbWidget();
        $ret = $jdb->fetchAll($sql);

        return $ret;
    }

    /**
     * Fonction permettant de sauvegarder les parametres
     * @return object $parametre
     *
     */
    public function ajouter ($parametre) {
        // instanciation de la factory
        $maFactory = jDao::get("commun~ao_injection_names");
        $records   = jDao::createRecord("commun~ao_injection_names");

        $records->libelle_injection       = $parametre->libelle_injection;
        if ($maFactory->insert($records)) {
            return $records->id;
        }

    }

     /**
     * Fonction permettant de modifier les v
     * @return object $partenaire
     *
     */
    public function modifier ($parametre) {
        // instanciation de la factory
        $maFactory = jDao::get("commun~ao_injection_names");
        $records   = $maFactory->get($parametre->id);

        $records->libelle_injection        = $parametre->libelle_injection;
 
        if ($maFactory->update($records)) {
            return $parametre->id;
        }
    }

     /**
     * Fonction permettant de checker les injections sur toutes les pages 
     * 
     */

    public static function checkInjection ($params) {

        jClasses::inc('commun~common');
        jClasses::inc('commun~parametre');

        $listeInterdit = common::liste('ao_injection_names');
        $stop = false;
        foreach ($params as $value){
             foreach ($listeInterdit as $data){
                $pos = strpos(strtolower($value), strtolower($data->libelle_injection));
                if ($pos !== false) {
                    $ip  = self::getIp();
                    //checker si cet ip est déjà en base 
                    $nbIp = self::checkIp($ip);

                    if (sizeof($nbIp)){
                        self::updateTentative($nbIp[0]);
                    } else {
                        self::insertInjection($ip);
                    }
                    /*Pour toute tentative d’injection, envoyez un mail à l’adresse X (administrable). Règles d’envoi :
                    Envoyer l’url utilisée
                    Envoyer le nombre de tentatives
                    Envoyer l’ip et la localisation de l’IP
                    Envoyer seulement après X tentatives et modulo 20 tentatives  */
                    if (sizeof($nbIp)){
                        $dataRetour = $nbIp[0];
                        // récupération de X : max tentative
                        $tentatives = parametre::get(PARAM_NB_TENTATIVE_INJECTION);

                        if ((($dataRetour->Nombre + 1) > $tentatives->param_content) && (($dataRetour->Nombre + 1) % 20 == 0)) {
                            $mailParam = new stdClass();
                            $link = 'http://' . $_SERVER['SERVER_NAME'] . jUrl::get($params['module'] . '~' . $params['action']);
                            $mailParam->usedUrl     = $link;
                            $mailParam->nbTentative = $dataRetour->Nombre + 1;
                            $mailParam->ip          = $ip . " " .self::getLocalisation();
                            $mailParam->detinataire = parametre::get(PARAM_MAIL_INJECTION)->param_content;
                            foreach ($params as $p)
                                $mailParam->param .= $p . " ";

                            self::sendMail($mailParam);
                        }
                        // die
                        if (($dataRetour->Nombre + 1) > $tentatives->param_content) 
                            die("Cette adresse IP a servi pour une tentative de piratage. Ce site lui est désormais interdit d'accès.");

                    }

                    $stop = true;
                    break;
                }
             }
             if ($stop) break;
        }
    }


    /**
     * Envoi de mail
     *
     */
     public static function sendMail($datas) {

        $mail = new PHPmailer();
        $mail->IsSMTP();
        $mail->IsHtml(true);
        $mail->AddAddress($datas->detinataire);
        $mail->Host         = $GLOBALS['gJConfig']->mailer['smtpHost'];
        $mail->Port         = $GLOBALS['gJConfig']->mailer['smtpPort'];
        $mail->Username     = 'Auto Occasion';
        $mail->From         = $GLOBALS['gJConfig']->mailer['webmasterEmail'];
        $mail->FromName     = 'Auto - occasion';
        $mail->Subject      = 'Tentative injection';
    
        $mail->Body         = '<b>Lien : </b>' . $datas->usedUrl .'</br> <b>Tentatives : </b>' .$datas->nbTentative . '</br> <b>Localisation</b>' . $datas->ip . '</br> <b>Les parametres :</b>' . $datas->param;
        
        if (!$mail->Send()){
          echo $mail->ErrorInfo;
          die('Sending mail - Error');
        }
        
        $mail->SmtpClose();
        $mail->ClearAddresses();
        unset($mail);
        
     }


     /**
     * Fonction permettant de checker les injections sur toutes les pages 
     * 
     */

    public static function updateTentative ($data) {
       $cnx = jDb::getConnection();

       $sql = " UPDATE ao_injection SET Nombre = ".($data->Nombre + 1) ." WHERE IdInjection = " . $data->IdInjection ;
       $cnx->exec($sql);
    }
     /**
     * Fonction permettant de checker les injections sur toutes les pages 
     * 
     */

    public static function checkIp ($ip) {

       $sql = " SELECT * FROM  ao_injection WHERE AdresseIp ='". $ip."' LIMIT 1";

       $jdb = jDb::getDbWidget();
       $ret = $jdb->fetchAll($sql);

       return $ret;

    }


     /**
     * Fonction permettant d'insérer adresseIp, tentative dans table ao_injection
     * 
     */

    public static function insertInjection ($ip) {

        // instanciation de la factory
        $maFactory = jDao::get("commun~ao_injection");
        $records   = jDao::createRecord("commun~ao_injection");

        $records->AdresseIp = $ip;
        $records->Nombre    = 1;
        $records->Date      = date("Y-m-d h:i:s");
        if ($maFactory->insert($records)) {
            return $records->id;
        }
    }


}